import warnings
warnings.warn("qturboframe.public_ui.ucf_h_ui.calendar模块已被废弃，替代模块为qturboframe.public_ui.h_ui.calendar", DeprecationWarning)

from time import sleep

from qturboframe.lib.report.log import logger
from qturboframe.lib.ranorex.exceptions import CsClientError
from qturboframe.lib.ranorex.web_element.div_tag import DivTag
from qturboframe.lib.ranorex.web_element.span_tag import SpanTag
from qturboframe.lib.ranorex.web_element.em_tag import EmTag
from qturboframe.lib.ranorex.web_element.i_tag import ITag
from qturboframe.lib.ranorex.web_element.input_tag import InputTag
from qturboframe.lib.ranorex.web_element.li_tag import LiTag
from qturboframe.lib.utils.__datatime_format__ import split_datetime, split_time
from qturboframe.lib.utils.check import CheckBasic
from ..ucf_base_element import BaseElement
from .button import Button


class Calendar(BaseElement, CheckBasic):
    """
    hui的日历控件操作

    :Attributes:
     - calendar_div: 日历控件的弹出框div元素
    """

    calendar_div = DivTag

    def __init__(self, element_para, father=None, timeout=10000):
        super().__init__(element_para, father, timeout)
        class_list = self._element.get_attribute('class').split(' ')
        if 'h-date-picker' not in class_list:
            self._element = self._element.find_element_by_attribute(
                'xpath', './ancestor::div[@class~\'h-date-picker\']', timeout=self.timeout)
        self._element = DivTag(self._element.control)

    def set_value(self, value):
        """
        hui日历控件赋值

        :Args:
         - value: 日期值或者日期范围

        :Usage:
         - calendar.set_value('20200420')
         - calendar.set_value('20200420 - 20200520')
        """
        # 数据驱动选项
        text_list = value.split(' - ')
        if len(text_list) == 1:
            self.set_value_for_single(text_list[0])
        elif len(text_list) == 2:
            self.set_value_for_range(text_list[0], text_list[1])
        else:
            raise AttributeError('日期参数格式不规范！')

    def set_value_for_single(self, value):
        """
        hui日历组件赋值

        :Args:
         - value: 日期值

        :Usage:
         - calendar.set_value_for_single('20200420')
         - calendar.set_value_for_single('2020/04/20')
         - calendar.set_value_for_single('2020-04-20')
        """
        re_displaynone = 'none'
        calendar_input = InputTag(self._element.find_element_by_attribute(
            'xpath', './/input', timeout=self.timeout).control)
        calendar_input.secure_click()

        calendar_div = self._element.exist(
            'xpath', './/div[@class~\'h-select-dropdown\']', timeout=100)
        if not calendar_div:
            self.calendar_div = DivTag(self._driver.find_element_by_attribute(
                'xpath', './body/div[@class~\'h-date-picker-dropdown-transfer\']',
                'style:display: block;', timeout=self.timeout).control)
        else:
            self.calendar_div = DivTag(calendar_div.control)
        # 数据处理
        text_list = value.split(' ')
        if len(text_list) == 1:
            date_text = text_list[0]
            time_text = None
        elif len(text_list) == 2:
            date_text = text_list[0]
            time_text = text_list[1]
        else:
            raise AttributeError('日期时间参数不符合日期规范！')
        year, month, day = split_datetime(date_text)
        # 选择year
        div_style = self.calendar_div.get_style('display')
        if re_displaynone not in div_style:
            self.__set_year(year)
        # 选择month
        div_style = self.calendar_div.get_style('display')
        if re_displaynone not in div_style:
            self.__set_month(month)
        # 选择day
        div_style = self.calendar_div.get_style('display')
        if re_displaynone not in div_style:
            self.__set_day(day)
        # 选择时间
        if time_text:
            hour, minute, second = split_time(time_text)
            # 选择hour
            div_style = self.calendar_div.get_style('display')
            time_span_btn = self.calendar_div.find_element_by_attribute(
                'xpath', './/div[@class~\'h-picker-confirm\']/span', 'text:选择时间', timeout=0.1)
            time_span_btn.secure_click()
            if re_displaynone not in div_style:
                self.__set_hour(hour)
            # 选择minute
                div_style = self.calendar_div.get_style('display')
            if re_displaynone not in div_style:
                self.__set_minute(minute)
            # 选择second
                div_style = self.calendar_div.get_style('display')
            if re_displaynone not in div_style:
                self.__set_second(second)
        # 确定
        if re_displaynone not in div_style:
            confirm_div = self.calendar_div.exist('xpath', './/div[@class~\'h-picker-confirm\']', timeout=100)
            if confirm_div:
                Button({'xpath': './/button[@class~\'h-btn\' and @innertext=\'确定\']'}, confirm_div,
                       1000).click()
            else:
                calendar_input.press_keys('{ESCAPE}')

    def set_value_for_range(self, value1, value2):
        """
        hui日历范围组件赋值

        :Args:
         - value: 日期值

        :Usage:
         - calendar.set_value_for_range('20200420 - 20200520')
         - calendar.set_value_for_range('2020/04/20 - 2020/05/20')
        """
        re_displaynone = 'none'
        calendar_input = InputTag(self._element.find_element_by_attribute(
            'xpath', './/input', timeout=self.timeout).control)
        calendar_input.secure_click()

        calendar_div = self._element.exist(
            'xpath', './/div[@class~\'h-select-dropdown\']', timeout=100)
        if not calendar_div:
            self.calendar_div = DivTag(self._driver.find_element_by_attribute(
                'xpath', './body/div[@class~\'h-date-picker-dropdown-transfer\']',
                'style:display: block;', timeout=self.timeout).control)
        else:
            self.calendar_div = DivTag(calendar_div.control)
        calendar_div_left = DivTag(self.calendar_div.find_element_by_attribute(
            'xpath', './/div[@class~\'h-date-picker-with-range\']/'
                     'div[class~\'h-picker-panel-body\']/div[@class~\'h-picker-panel-content-left\']',
            timeout=self.timeout).control)
        calendar_div_right = DivTag(self.calendar_div.find_element_by_attribute(
            'xpath', './/div[@class~\'h-date-picker-with-range\']/'
                     'div[class~\'h-picker-panel-body\']/div[@class~\'h-picker-panel-content-right\']',
            timeout=self.timeout).control)
        # 数据处理
        text_list1 = value1.split(' ')
        if len(text_list1) == 1:
            date_text1 = text_list1[0]
            time_text1 = None
        elif len(text_list1) == 2:
            date_text1 = text_list1[0]
            time_text1 = text_list1[1]
        else:
            raise AttributeError('日期时间参数不符合日期规范！')
        year1, month1, day1 = split_datetime(date_text1)
        text_list2 = value2.split(' ')
        if len(text_list2) == 1:
            date_text2 = text_list2[0]
            time_text2 = None
        elif len(text_list2) == 2:
            date_text2 = text_list2[0]
            time_text2 = text_list2[1]
        else:
            raise AttributeError('日期时间参数不符合日期规范！')
        year2, month2, day2 = split_datetime(date_text2)
        temp_div = self.calendar_div
        self.calendar_div = calendar_div_left
        # 选择year1
        div_style = temp_div.get_style('display')
        if re_displaynone not in div_style:
            self.__set_year(year1)
        # 选择month1
        div_style = temp_div.get_style('display')
        if re_displaynone not in div_style:
            self.__set_month(month1)
        # 选择day1
        div_style = temp_div.get_style('display')
        if re_displaynone not in div_style:
            self.__set_day(day1)
        self.calendar_div = calendar_div_right
        # 选择year2
        div_style = temp_div.get_style('display')
        if re_displaynone not in div_style:
            self.__set_year(year2)
        # 选择month2
        div_style = temp_div.get_style('display')
        if re_displaynone not in div_style:
            self.__set_month(month2)
        # 选择day2
        div_style = temp_div.get_style('display')
        if re_displaynone not in div_style:
            self.__set_day(day2)
        # 选择时间1
        if time_text1:
            hour, minute, second = split_time(time_text1)
            # 选择hour
            div_style = temp_div.get_style('display')
            time_span_btn = SpanTag(temp_div.find_element_by_attribute(
                'xpath', './/div[@class~\'h-picker-confirm\']/span', 'text:选择时间', timeout=0.1).control)
            time_span_btn.secure_click()
            time_div_left = DivTag(temp_div.find_element_by_attribute(
                'xpath', './/div[@class~\'h-time-picker-with-range\']/'
                         'div[@class~\'h-picker-panel-body\']/div[@class~\'h-picker-panel-content-left\']',
                timeout=self.timeout).control)
            self.calendar_div = time_div_left
            if re_displaynone not in div_style:
                self.__set_hour(hour)
            # 选择minute
            div_style = temp_div.get_style('display')
            if re_displaynone not in div_style:
                self.__set_minute(minute)
            # 选择second
            div_style = temp_div.get_style('display')
            if re_displaynone not in div_style:
                self.__set_second(second)
        # 选择时间2
        if time_text2:
            hour, minute, second = split_time(time_text2)
            time_div_right = DivTag(temp_div.find_element_by_attribute(
                'xpath', './/div[@class~\'h-time-picker-with-range\']/'
                         'div[@class~\'h-picker-panel-body\']/div[@class~\'h-picker-panel-content-right\']',
                timeout=self.timeout).control)
            self.calendar_div = time_div_right
            # 选择hour
            div_style = temp_div.get_style('display')
            if re_displaynone not in div_style:
                self.__set_hour(hour)
            # 选择minute
            div_style = temp_div.get_style('display')
            if re_displaynone not in div_style:
                self.__set_minute(minute)
            # 选择second
            div_style = temp_div.get_style('display')
            if re_displaynone not in div_style:
                self.__set_second(second)

            # 确定
            if re_displaynone not in div_style:
                confirm_div = self.calendar_div.exist('xpath', './/div[@class~\'h-picker-confirm\']', timeout=100)
                if confirm_div:
                    Button({'xpath': './/button[@class~\'h-btn\' and @innertext=\'确定\']'}, confirm_div,
                           1000).click()
                else:
                    calendar_input.press_keys('{ESCAPE}')

    def __set_year(self, year):
        head_div = DivTag(self.calendar_div.find_element_by_attribute(
            'xpath', './/div[@class~\'h-date-picker-header\']', timeout=self.timeout).control)
        year_span_button = SpanTag(head_div.find_elements_by_attribute(
                'xpath', './span/span[@class~\'h-date-picker-header-label\']', timeout=self.timeout)[0].control)
        year_span_button.secure_click()
        year_div = DivTag(self.calendar_div.find_element_by_attribute(
            'xpath', './/div[@class~\'h-date-picker-cells-year\']', timeout=self.timeout).control)
        year_spans = [EmTag(webelement.control) for webelement in
                      year_div.find_elements_by_attribute('xpath', './span/em', timeout=self.timeout)]
        if int(year_spans[0].text) > int(year):
            year_prev_button = SpanTag(head_div.find_element_by_attribute(
                'xpath', './/span[@class~\'h-date-picker-prev-btn\']', timeout=self.timeout).control)
            year_prev_button.secure_click()
            self.__set_year(year)
        elif int(year_spans[-1].text) < int(year):
            year_next_button = SpanTag(head_div.find_element_by_attribute(
                'xpath', './/span[@class~\'h-date-picker-next-btn\']', timeout=self.timeout).control)
            year_next_button.secure_click()
            self.__set_year(year)
        else:
            for year_span in year_spans:
                while 1==1:
                    year_text = year_span.text
                    break
                try:
                    year_int = int(year_text)
                except:
                    continue
                if year_int == int(year):
                    year_span.secure_click()
                    break

    def __set_month(self, month):
        month_div = DivTag(self.calendar_div.find_element_by_attribute(
            'xpath', './/div[@class~\'h-date-picker-cells-month\']', timeout=self.timeout).control)
        month_spans = [SpanTag(webelement.control) for webelement in
                       month_div.find_elements_by_attribute('xpath', './/span', timeout=self.timeout)]
        month_spans[int(month) - 1].secure_click()

    def __set_day(self, day):
        re_old = r'h-date-picker-cells-cell-prev-month'
        re_new = r'h-date-picker-cells-cell-next-month'
        day_div = DivTag(self.calendar_div.find_element_by_attribute(
            'xpath', './/div[@class~\'h-date-picker-cells\']', timeout=self.timeout).control)
        # day_ems = [EmTag(webelement.control) for webelement in day_div.find_elements_by_attribute(
        #     'xpath', './span/em[@innertext=\'{}\']'.format(day), timeout=self.timeout)]
        # for day_em in day_ems:
        #     day_span = SpanTag(day_em.find_element_by_attribute(
        #         'xpath', './parent::span', timeout=self.timeout).control)
        #     day_span_class_list = day_span.get_attribute('class').split(' ')
        #     if re_old not in day_span_class_list and re_new not in day_span_class_list:
        #         day_span.secure_click()
        #         break
        day_spans = [SpanTag(webelement.control) for webelement in day_div.find_elements_by_attribute(
            'xpath', './span', 'text:{}'.format(int(day)), timeout=self.timeout)]
        print(len(day_spans))
        for day_span in day_spans:
            print(1111)
            day_span_class_list = day_span.get_attribute('class').split(' ')
            if re_old not in day_span_class_list and re_new not in day_span_class_list:
                print(2222)
                day_span.secure_click()
                break

    def __set_hour(self, hour):
        re_displaynone = 'none'
        head_div = DivTag(self.calendar_div.find_elements_by_attribute(
            'xpath', './/div[@class~\'h-time-picker-cells\']/div[@class~\'h-time-picker-cells-list\']',
            timeout=self.timeout)[0].control)
        div_style = head_div.get_style('display')
        if re_displaynone not in div_style:
            hour_li = LiTag(head_div.find_elements_by_attribute('xpath',
                './/ul[@class~\'h-time-picker-cells-ul\']/li[@class~\'h-time-picker-cells-cell\']',
                                                                timeout=self.timeout)[int(hour)].control)
            hour_li.focus()
            hour_li.secure_click()

    def __set_minute(self, minute):
        re_displaynone = 'none'
        head_div = DivTag(self.calendar_div.find_elements_by_attribute(
            'xpath', './/div[@class~\'h-time-picker-cells\']/div[@class~\'h-time-picker-cells-list\']',
            timeout=self.timeout)[1].control)
        div_style = head_div.get_style('display')
        if re_displaynone not in div_style:
            minute_li = LiTag(head_div.find_elements_by_attribute('xpath',
                './/ul[@class~\'h-time-picker-cells-ul\']/li[@class~\'h-time-picker-cells-cell\']',
                                                                  timeout=self.timeout)[int(minute)].control)
            minute_li.focus()
            minute_li.secure_click()

    def __set_second(self, second):
        re_displaynone = 'none'
        head_div = DivTag(self.calendar_div.find_elements_by_attribute(
            'xpath', './/div[@class~\'h-time-picker-cells\']/div[@class~\'h-time-picker-cells-list\']',
            timeout=self.timeout)[2].control)
        div_style = head_div.get_style('display')
        if re_displaynone not in div_style:
            second_li = LiTag(head_div.find_elements_by_attribute('xpath',
                './/ul[@class~\'h-time-picker-cells-ul\']/li[@class~\'h-time-picker-cells-cell\']',
                                                                  timeout=self.timeout)[int(second)].control)
            second_li.focus()
            second_li.secure_click()

    def clear(self):
        """
        hui日历控件值清除选项值

        :Example:
         - 例: calendar.clear()
        """
        self._element.move_to()
        clear_i = self._element.exist(
            'xpath', './/div[@class~\'h-select-selection\']/i[@class~\'h-icon-close\']',
            timeout=self.timeout)
        if clear_i:
            clear_i = ITag(clear_i.control)
            clear_i.secure_click()
        else:
            raise CsClientError('没有清除按钮，无法删除！')

    def is_default(self, value):
        """
        检查hui日历控件默认值

        :Args:
         - value: 待检查的选项值

        :Returns:
            匹配返回True，否则返回False

        :Example:
         - 例1: calendar.is_default('20200420')
         - 例2: calendar.is_default('2020/04/20')
         - 例3calendar.is_default('2020-04-20')
        """
        inputele = InputTag(self._element.find_element_by_attribute(
            'xpath', './/input', timeout=self.timeout).control)
        inputele.focus()
        if inputele.get_attribute('value'):
            text = inputele.get_attribute('value')
        elif inputele.get_attribute('placeholder'):
            text = inputele.get_attribute('placeholder')
        elif inputele.get_attribute('defaultValue'):
            text = inputele.get_attribute('defaultValue')
        else:
            text = ''
        if text:
            if text == value:
                return True
            else:
                logger.error('默认值不匹配！')
                return False
        else:
            logger.error('没有默认值！')
            return False

    def is_nonnull(self):
        '''
        检查hui日历控件是否有非空属性

        :Returns:
            非空返回True，否则返回False

        :Example:
         - 例: calendar.is_nonnull()
        '''
        self._element.focus()
        form_item = DivTag(self._element.find_element_by_attribute(
            'xpath', './ancestor::div[@class~\'h-form-item-content\']/'
                     'parent::div[@class~\'h-form-item\']', timeout=self.timeout).control)
        item_class_list = form_item.get_attribute('class').split(' ')
        if 'h-form-item-required' in item_class_list:
            return True
        else:
            return False

    def check_default(self, value):
        '''
        校验hui日历控件默认值

        :Args:
         - value: 待检查的选项值

        :Raises:
            SeleniumError: 日历控件默认值校验不通过

        :Example:
         - 例1: calendar.check_default('20200420')
         - 例2: calendar.check_default('2020/04/20')
         - 例3: calendar.check_default('2020-04-20')
        '''
        if not self.is_default(value):
            raise CsClientError('日历控件默认值校验不通过！')

    def check_nonull(self):
        '''
        校验hui日历控件是否非空

        :Raises:
            SeleniumError: 日历控件非空校验不通过

        :Example:
         - 例: calendar.check_nonull()
        '''
        if not self.is_nonnull():
            raise CsClientError('日历控件非空校验不通过！')